
import logging
import hashlib
import os
import popen2

from django.core.exceptions import ObjectDoesNotExist

from django.shortcuts import render_to_response
from django.shortcuts import get_object_or_404
from django.http import Http404, HttpResponse, HttpResponseRedirect
from django import newforms as forms
from django.newforms import form_for_model,form_for_instance

#from django.http import HttpResponseRedirect
from django.contrib.auth.decorators import login_required
from django.views.decorators.cache import cache_control

from ca.models import Certificate

from django.conf import settings


@login_required
def newP2PCert(request):

    domain = '%s@%s'%(request.user.username,settings.OVERLAY)
    key=''
    cert=''
    
    c = Certificate( owner=request.user.username, name=domain, cert=cert, key=key )
    c.save()
    id = c.id

    peerid = hashlib.sha1(str(id)).hexdigest()[-32:]

    base = settings.CERT_DIR
    p = popen2.Popen4("%s/makeCert %s %s %s@%s"%(base,base,domain,peerid,settings.OVERLAY))
    log = p.fromchild.read();
    p.wait()
    
    f = open('%s/%s.key'%(base,domain))
    try:
        key = f.read()
    finally:
        f.close()
        
    f = open('%s/%s.cer'%(base,domain))
    try:
        cert = f.read()
    finally:
        f.close()
                 
    c.cert= cert
    c.key = key
    c.peerid = peerid

    c.save()

    return HttpResponseRedirect('/cert/%s/'%id)


class SignP2PForm(forms.Form):
    csr = forms.CharField(max_length=10000,required=True)


@login_required
def signP2PCert(request):
    if request.method == 'POST':
        form = SignP2PForm(request.POST)
        if form.is_valid():
            # Do form processing here...
            csr = form.cleaned_data['csr']

            domain = '%s@%s'%(request.user.username,settings.OVERLAY)
            key=''
            cert=''

            c = Certificate( owner=request.user.username, name=domain, cert=cert, key=key )
            c.save()
            id = c.id


            base = settings.CERT_DIR

            f = open('%s/%s.csr'%(base,id),"w")
            try:
                f.write( csr )
            finally:
                f.close()
            

            numPeerIds = 3
            peerid = hashlib.sha1( str(id)+":"+str(0) ).hexdigest()[-32:]
            san = 'URI:%s:%s@%s'%(settings.OVERLAY_SCHEME, peerid, settings.OVERLAY)

            for i in range( 1,numPeerIds ):
                peerid = hashlib.sha1( str(id)+":"+str(i) ).hexdigest()[-32:]
                san += ',URI:%s:%s@%s'%(settings.OVERLAY_SCHEME, peerid, settings.OVERLAY)

            p = popen2.Popen4("%s/signCert %s %s %s"%(base,base,id,san ))
            log = p.fromchild.read();
            p.wait()
            
            f = open('%s/%s.cer'%(base,id))
            try:
                cert = f.read()
            finally:
                f.close()
                 
            c.cert= cert
            c.key = ''
            c.peerid = peerid

            c.save()

            return HttpResponseRedirect('/cert/%s/'%id)
    else:
        form = SipCertForm()
    return render_to_response('signP2P.html', {'form': form })


class SipCertForm(forms.Form):
    domainName = forms.CharField(max_length=128,required=True)


@login_required
def newSipCert(request):
    if request.method == 'POST':
        form = SipCertForm(request.POST)
        if form.is_valid():
            # Do form processing here...
            name = form.cleaned_data['domainName']

            #filter name carefully to stop scripting attacks 
            domain = ''
            for c in name[0:126].lower():
                if (c>='0') and (c<='9'): domain += c
                if (c>='a') and (c<='z'): domain += c
                if (c == '.'): domain += c
                
            key=''
            cert=''

            c = Certificate( owner=request.user.username, name=domain, cert=cert, key=key )
            c.save()
            id = c.id

            base = settings.CERT_DIR
            p = popen2.Popen4("%s/makeCert %s %s"%(base,base,domain))
            log = p.fromchild.read();
            p.wait()
            
            f = open('%s/%s.key'%(base,domain))
            try:
                key = f.read()
            finally:
                f.close()
                
            f = open('%s/%s.cer'%(base,domain))
            try:
                cert = f.read()
            finally:
                f.close()
                 
            c.cert= cert
            c.key = key

            c.save()

            return HttpResponseRedirect('/cert/%s/'%id)
    else:
        form = SipCertForm()
    return render_to_response('createSip.html', {'form': form })



@cache_control(private=True)
def showCert(request,id):
    dict = {}
    dict['cert'] = ''
    dict['key'] = ''
    dict['domain'] = ''
    dict['havePrivateKey'] = 0
    dict['haveCert'] = 0
    dict['id'] = id
    dict['peerid'] = ''

    if ( int(id) == 0 ):
        dict['domain'] = "Root Certificate"
        dict['cert'] = ''
        dict['haveCert'] = 1

        base = settings.CERT_DIR
        f = open('%s/demoCA/cacert.pem'%(base))
        try:
            dict['cert'] = f.read()
        finally:
            f.close()
    else:
        c = Certificate.objects.get( id=id )

        dict['domain'] = c.name
        dict['peerid'] = c.peerid
        dict['cert'] = c.cert
        dict['haveCert'] = 1

        if request.user.is_authenticated() :
            if request.user.username == c.owner :
                dict['key'] = c.key
                dict['havePrivateKey'] = 1

    return render_to_response('cert.html' , dict )
